﻿using Microsoft.AspNetCore.Builder.Extensions;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using My.Framework.AspNetCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using System.Security.Claims;

namespace My.Framework
{
    /// <summary>
    /// 应用程序
    /// </summary>
    public static class App
    {
        private static IServiceCollection? _serviceCollection;
		public static WebApplication? _host { get; set; }
		public static IHttpContextAccessor? _httpContextAccessor { get; set; }
		public static List<IStartupModule> _startups { get; set; } = new List<IStartupModule>();

		/// <summary>
		/// IServiceCollection
		/// </summary>
		public static IServiceCollection? Services => _serviceCollection;

        /// <summary>
        /// HttpContext
        /// </summary>
        public static HttpContext? HttpContext => _httpContextAccessor?.HttpContext;

        /// <summary>
        /// IServiceProvider
        /// </summary>
        public static IServiceProvider? ServiceProvider => _host?.Services;

        /// <summary>
        /// 全局配置构建器
        /// </summary>
        public static IConfiguration Configuration { get; set; }


		/// <summary>
		/// 程序启动器集合
		/// </summary>
        public static IStartupModule[] Startups => _startups.ToArray();

		/// <summary>
		/// 获取请求上下文用户
		/// </summary>
		/// <remarks>只有授权访问的页面或接口才存在值，否则为 null</remarks>
		public static ClaimsPrincipal User => HttpContext?.User;

		/// <summary>
		/// 添加 StartupModule 
		/// </summary>
		/// <typeparam name="TStartupModule"></typeparam>
		/// <param name="builder"></param>
		/// <param name="options"></param>
		/// <returns></returns>
		public static WebApplicationBuilder AddStartupModule<TStartupModule>(
			this WebApplicationBuilder builder
		)
			where TStartupModule : IStartupModule
		{
			_serviceCollection = builder.Services;

			if (Activator.CreateInstance(typeof(TStartupModule)) is IStartupModule startup)
			{
				Configuration = builder.Configuration;

				_startups.Clear();

				var allImportStartup = startup?.GetAllImportStartup();

				var appStartupsOrderBy = allImportStartup?.OrderBy(w => w.Order).ToList();

				if (appStartupsOrderBy != null && appStartupsOrderBy.Count > 0)
				{
					_startups.AddRange(appStartupsOrderBy);
				}

				foreach (var item in _startups)
				{
					item?.ConfigureServices(builder);
				}
			}

			return builder;
		}

		/// <summary>
		/// 获取选项
		/// </summary>
		/// <typeparam name="TOptions">强类型选项类</typeparam>
		/// <param name="serviceProvider"></param>
		/// <returns>TOptions</returns>
		public static TOptions GetOptions<TOptions>(IServiceProvider serviceProvider = default)
			where TOptions : class, new()
		{
			return GetService<IOptions<TOptions>>(serviceProvider ?? ServiceProvider).Value;
		}

		/// <summary>
		/// 获取配置
		/// </summary>
		/// <typeparam name="TOptions">强类型选项类</typeparam>
		/// <param name="path">配置中对应的Key</param>
		/// <param name="loadPostConfigure"></param>
		/// <returns>TOptions</returns>
		public static TOptions GetConfig<TOptions>(string path, bool loadPostConfigure = false)
		{
			var options = Configuration.GetSection(path).Get<TOptions>();

			return options;
		}

		/// <summary>
		/// 获取请求生存周期的服务
		/// </summary>
		/// <typeparam name="TService"></typeparam>
		/// <param name="serviceProvider"></param>
		/// <returns></returns>
		public static TService GetService<TService>(IServiceProvider serviceProvider = default)
			where TService : class
		{
			return GetService(typeof(TService), serviceProvider) as TService;
		}

		/// <summary>
		/// 获取请求生存周期的服务
		/// </summary>
		/// <param name="type"></param>
		/// <param name="serviceProvider"></param>
		/// <returns></returns>
		public static object GetService(Type type, IServiceProvider serviceProvider = default)
		{
			return (serviceProvider ?? ServiceProvider).GetService(type);
		}

		/// <summary>
		/// 获取请求生命周期的服务
		/// </summary>
		/// <param name="type"></param>
		/// <returns></returns>
		public static object GetService(Type type)
		{
			return ServiceProvider.GetService(type);
		}

		/// <summary>
		/// 处理获取对象异常问题
		/// </summary>
		/// <typeparam name="T">类型</typeparam>
		/// <param name="action">获取对象委托</param>
		/// <param name="defaultValue">默认值</param>
		/// <returns>T</returns>
		private static T CatchOrDefault<T>(Func<T> action, T defaultValue = null)
			where T : class
		{
			try
			{
				return action();
			}
			catch
			{
				return defaultValue ?? null;
			}
		}

		/// <summary>
		/// 创建服务域
		/// </summary>
		/// <returns></returns>
		public static IServiceScope? CreateScope() => _host?.Services?.CreateScope();

		/// <summary>
		/// 获取请求生命周期的服务
		/// </summary>
		/// <param name="type"></param>
		/// <returns></returns>
		public static object GetRequiredService(Type type)
		{
			return ServiceProvider.GetRequiredService(type);
		}

		/// <summary>
		/// 获取请求生命周期的服务
		/// </summary>
		/// <typeparam name="TService"></typeparam>
		/// <returns></returns>
		public static TService GetRequiredService<TService>()
			where TService : class
		{
			return GetRequiredService(typeof(TService)) as TService;
		}
	}
}
